package eu.sweetlygeek.scrobbler.graphical;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import eu.sweetlygeek.scrobbler.PhoneScrobbler;
import eu.sweetlygeek.scrobbler.exception.ScrobblerException;

@SuppressWarnings("serial")
public class Credentials extends JDialog {

	private static final String PASSWORD = "password";
	private static final String USER = "user";
	private static final char[] HEX_CHARS = {'0', '1', '2', '3',
		'4', '5', '6', '7',
		'8', '9', 'a', 'b',
		'c', 'd', 'e', 'f',};
	private static final String CONF_FILE = ".bScrobbler";

	private static Credentials instance;

	private JTextField userField;
	private JPasswordField passwordField;

	private Credentials()
	{
		super();
		this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		this.setTitle("Credentials");
		this.setLayout(new GridLayout(3,2));
		this.add(new JLabel("User :"));
		userField = new JTextField();
		this.add(userField);
		this.add(new JLabel("Password :"));
		passwordField = new JPasswordField();
		this.add(passwordField);
		JButton ok = new JButton("OK");
		ok.addActionListener(new ButtonListener(true));
		this.add(ok);
		JButton cancel = new JButton("Cancel");
		cancel.addActionListener(new ButtonListener(false));
		this.add(cancel);
	}
	
	public static void destroy()
	{
		if (instance != null)
		{
			instance.dispose();
		}
	}
	
	private void saveCredentials(String user, String password) throws ScrobblerException
	{
		try {
			Properties properties = new Properties();
			properties.put(USER, user);
			properties.put(PASSWORD, password);
			String homeDir = System.getProperty("user.home");
			File conf = new File(homeDir, CONF_FILE);
			properties.store(new FileWriter(conf), null);
		} catch (IOException e) {
			throw new ScrobblerException("Error while saving credentials", e);
		}
	}

	private String to32MD5String(char[] password) throws ScrobblerException 
	{
		try {
			MessageDigest digest = MessageDigest.getInstance("MD5");
			for (int i = 0; i < password.length; i++)
			{
				digest.update((byte) password[i]);
			}
			return byteArrayToHexString(digest.digest());
		} catch (NoSuchAlgorithmException e) {
			throw new ScrobblerException("Error while hashing password", e);
		}
	}

	private String byteArrayToHexString(byte[] hash)
	{
		char buf[] = new char[hash.length * 2];
		for (int i = 0, x = 0; i < hash.length; i++) {
			buf[x++] = HEX_CHARS[(hash[i] >>> 4) & 0xf];
			buf[x++] = HEX_CHARS[hash[i] & 0xf];
		}
		return new String(buf);
	}

	public static void launch() throws ScrobblerException
	{
		String homeDir = System.getProperty("user.home");
		File conf = new File(homeDir, CONF_FILE);
		if (conf.exists())
		{
			try {
				Properties props = new Properties();
				props.load(new FileReader(conf));
				PhoneScrobbler.openFiles(props.getProperty(USER), props.getProperty(PASSWORD));
			} catch (IOException e) {
				throw new ScrobblerException("Error while loading configuration", e);
			}
		}
		else
		{
			if (instance == null)
			{
				instance = new Credentials();
			}
			instance.pack();
			instance.setVisible(true);	
		}
		destroy();
	}
	
	private class ButtonListener implements ActionListener
	{
		private boolean ok;
		
		public ButtonListener(boolean ok)
		{
			this.ok = ok;
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			if (ok)
			{
				String user = userField.getText();
				try {
					String password = to32MD5String(passwordField.getPassword());
					saveCredentials(user, password);
					destroy();
					PhoneScrobbler.openFiles(user, password);
				} catch (ScrobblerException e1) {
					PhoneScrobbler.displayError("Error while scrobbling", e1);
				}
			}
			else
			{
				destroy();
			}
		}
	}

}
